home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / samples / dpmi / pktdrvr.c < prev    next >
C/C++ Source or Header  |  1993-08-08  |  5KB  |  220 lines

  1. #include <sys/types.h>
  2. #include <stdio.h>
  3. #include <go32.h>
  4. #include <dos.h>
  5. #include <dpmi.h>
  6. #include <string.h>
  7. #include <pc.h>
  8.  
  9. _go32_dpmi_seginfo dosmem;
  10. int rmbuffer_full = 0;
  11.  
  12. int pd_test(int vector)
  13. {
  14.   char sig[9];
  15.   unsigned short vec[2];
  16.   unsigned long pkt_addr;
  17.   dosmemget(vector*4, 4, vec);
  18.   pkt_addr = vec[1] * 16 + vec[0];
  19.   if (pkt_addr == 0)
  20.     return 0;
  21.   dosmemget(pkt_addr+3, 9, sig);
  22.   if (strcmp(sig, "PKT DRVR"))
  23.     return 0;
  24.   return 1;
  25. }
  26.  
  27. void pd_get_etheraddr(int v, char *buf, int len)
  28. {
  29.   _go32_dpmi_registers reg;
  30.   memset(®, 0, sizeof(reg));
  31.   reg.h.ah = 6;
  32.   reg.x.bx = 0;
  33.   reg.x.di = _go32_info_block.linear_address_of_transfer_buffer & 15;
  34.   reg.x.es = _go32_info_block.linear_address_of_transfer_buffer >> 4;
  35.   reg.x.cx = len;
  36.   _go32_dpmi_simulate_int(v, ®);
  37.   dosmemget(_go32_info_block.linear_address_of_transfer_buffer, len, buf);
  38. }
  39.  
  40. void pd_send(int v, void *packet, int length)
  41. {
  42.   _go32_dpmi_registers reg;
  43.   memset(®, 0, sizeof(reg));
  44.   reg.h.ah = 4;
  45.   reg.x.si = _go32_info_block.linear_address_of_transfer_buffer & 15;
  46.   reg.x.ds = _go32_info_block.linear_address_of_transfer_buffer >> 4;
  47.   reg.x.cx = length;
  48.   dosmemput(packet, length, _go32_info_block.linear_address_of_transfer_buffer);
  49.   _go32_dpmi_simulate_int(v, ®);
  50. }
  51.  
  52. volatile int rmcb_happened = 0;
  53. _go32_dpmi_registers rmcb_registers;
  54.  
  55. void rmcb(_go32_dpmi_registers *reg)
  56. {
  57.   if (reg->x.ax == 0)
  58.   {
  59.     if (rmcb_happened)
  60.       reg->x.es = 0;
  61.     else
  62.       reg->x.es = dosmem.rm_segment;
  63.     reg->x.di = 0;
  64.   }
  65.   else
  66.   {
  67.     rmcb_happened = reg->x.cx;
  68.   }
  69. }
  70.  
  71. int pd_read(char *buf)
  72. {
  73.   int len = rmcb_happened;
  74.   while (!rmcb_happened && !kbhit());
  75.   if (kbhit())
  76.   {
  77.     getkey();
  78.     return 0;
  79.   }
  80.   dosmemget(dosmem.rm_segment*16, len, buf);
  81.   rmcb_happened = 0;
  82.   return len;
  83. }
  84.  
  85. char test_arp[64] = {
  86.   0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  87.   0, 0, 0, 0, 0, 0,
  88.   0x08, 0x06,
  89.   0, 1, 8, 0, 6, 4, 0, 1,
  90.   0, 0, 0, 0, 0, 0,
  91.   0, 0, 0, 0,
  92.   0, 0, 0, 0, 0, 0,
  93.   0, 0, 0, 0,
  94. };
  95.  
  96. void pd_do(int v)
  97. {
  98.   unsigned char ether[6];
  99.   int i;
  100.   _go32_dpmi_registers regs;
  101.   _go32_dpmi_seginfo rmcb_seginfo;
  102.   int handle;
  103.  
  104.   printf("Packet driver detected at vector 0x%02x\n", v);
  105.  
  106.   pd_get_etheraddr(v, ether, 6);
  107.   printf("This machine's ethernet address is %02x:%02x:%02x:%02x:%02x:%02x\n",
  108.     ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);
  109.  
  110.   rmcb_seginfo.pm_offset = (int)rmcb;
  111.   if ((i=_go32_dpmi_allocate_real_mode_callback_retf(&rmcb_seginfo, &rmcb_registers)) != 0)
  112.   {
  113.     printf("Error: cannot allocate real mode callback, error=%04x\n", i);
  114.     return;
  115.   }
  116.   printf("real mode callback is at %04x:%04x\n", rmcb_seginfo.rm_segment, rmcb_seginfo.rm_offset);
  117.  
  118.   memset(®s, 0, sizeof(regs));  
  119.   regs.x.es = rmcb_seginfo.rm_segment;
  120.   regs.x.di = rmcb_seginfo.rm_offset;
  121.   regs.h.ah = 2;
  122.   regs.h.al = 1;
  123.   regs.x.bx = 0xffff;
  124.   regs.h.dl = 0;
  125.   regs.x.cx = 0;
  126.   _go32_dpmi_simulate_int(v, ®s);
  127.   if (regs.x.flags & 1)
  128.   {
  129.     printf("Error: packet driver receive accept refused\n");
  130.     return;
  131.   }
  132.   handle = regs.x.ax;
  133.   printf("packet driver acceptor allocated, handle = %d\n", handle);
  134.  
  135.   memcpy(test_arp+6, ether, 6);
  136.   memcpy(test_arp+22, ether, 6);
  137.   pd_send(v, test_arp, 64);
  138.   printf("ARP packet sent, waiting.  Press a key to abort.\n");
  139.   
  140.   while (!kbhit() && !rmcb_happened);
  141.   if (kbhit())
  142.   {
  143.     printf("Keyboard interrupt\n");
  144.     getkey();
  145.   }
  146.   if (rmcb_happened)
  147.   {
  148.     unsigned char pkt[1600];
  149.     int len;
  150.     printf("Callback happened\n");
  151.     len = pd_read(pkt);
  152.     rmcb_happened = 0;
  153.     printf("Other machine's IP address is %02x:%02x:%02x:%02x:%02x:%02x\n",
  154.       pkt[22], pkt[23], pkt[24], pkt[25], pkt[26], pkt[27]);
  155.   }
  156.  
  157.   memset(®s, 0, sizeof(regs));  
  158.   regs.h.ah = 3;
  159.   regs.x.bx = handle;
  160.   _go32_dpmi_simulate_int(v, ®s);
  161.   printf("packet driver acceptor released\n");
  162.   
  163.   _go32_dpmi_free_real_mode_callback(&rmcb_seginfo);
  164.   printf("real mode callback released\n");
  165. }
  166.  
  167. void get_ip_address(char *msg, unsigned char *buffer)
  168. {
  169.   int i[4], k;
  170.   while (1)
  171.   {
  172.     int invalid = 0;
  173.     i[3] = -1;
  174.     fputs(msg, stdout);
  175.     fflush(stdout);
  176.     scanf("%d.%d.%d.%d", i+0, i+1, i+2, i+3);
  177.     for (k=0; k<4; k++)
  178.     {
  179.       if (i[k] < 0 || i[k] > 255)
  180.         invalid = 1;
  181.       else
  182.         buffer[k] = i[k];
  183.     }
  184.     if (!invalid)
  185.       return;
  186.     printf("Invalid IP address.  Expected something like 128.0.0.7\n");
  187.   }
  188. }
  189.  
  190. int main()
  191. {
  192.   int v;
  193.  
  194.   printf("Packet Driver test - arp\n");
  195.   get_ip_address("Enter this machine's IP address  : ", test_arp+28);
  196.   get_ip_address("Enter other machine's IP address : ", test_arp+38);
  197.  
  198.   printf("go32 segments: cs=%04x ds=%04x ss=%04x\n", _go32_my_cs(), _go32_my_ds(), _go32_my_ss());
  199.  
  200.   dosmem.size = 100;
  201.   if (_go32_dpmi_allocate_dos_memory(&dosmem))
  202.   {
  203.     printf("Unable to allocate dos memory - max size is %d\n", dosmem.size);
  204.     exit(1);
  205.   }
  206.   printf("dos buffer at 0x%04x:0\n", dosmem.rm_segment);
  207.  
  208.  
  209.   for (v=0x60; v<0x80; v++)
  210.   {
  211.     if (pd_test(v))
  212.       pd_do(v);
  213.   }
  214.  
  215.   _go32_dpmi_free_dos_memory(&dosmem);
  216.   printf("dos buffer released\n");
  217.  
  218.   return 0;
  219. }
  220.